/*
 * Main.java
 *
 * Created on 2 September 2006, 1:37
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package fasea;

import fasea.constants.Constants;
import fasea.model.FaseaModel;
import fasea.ui.utils.ImageControl;
import fasea.ui.properties.PropertiesController;
import fasea.ui.properties.PropertiesView;
import fasea.ui.properties.PropertiesViewImpl;
import fasea.ui.search.SearchController;
import fasea.ui.search.SearchView;
import fasea.ui.search.SearchViewImpl;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import javax.swing.JOptionPane;
import javax.swing.UIManager;

/**
 *
 * @author gvasil
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws Exception {
        if (isAlreadyRunning()) {
            return;
        }
        createShutdownHook();
        if (isFirstCall()) {
            createApplicationDirectoriesAndPropFile();
        }
        

        // Set System L&F
        UIManager.setLookAndFeel(
                UIManager.getSystemLookAndFeelClassName());
        
        FaseaModel model = new FaseaModel();
        SearchView searchView = new SearchViewImpl();
        SearchController searchController = new SearchController();
        searchController.bindModel(model);
        searchController.bindView(searchView);
        
        PropertiesView propertiesView = new PropertiesViewImpl(searchView.getFrame());
        PropertiesController propertiesController = new PropertiesController();
        propertiesController.bindModel(model);
        propertiesController.bindView(propertiesView);
        
        model.init();

        

        /*
         * Updater update = new Updater();
         *
         * try { if (update.isUpdated() == false) {
         * JOptionPane.showMessageDialog(null, "<html>" + "The Fasea version
         * that is currently running appears to be old. <br/><br/>" + "You can
         * update Fasea manually by visiting this link and <br/>" + "downloading
         * the latest version:<p align=\"center\">" + "<a href=\"" +
         * Resources.getApplicationWebsite() + "\">" +
         * Resources.getApplicationWebsite() + "</p></a><br/></html>", "Update
         * found", JOptionPane.INFORMATION_MESSAGE); } } catch (Exception ex) {
         * // checking for updates fail for some reason; do nothing }
         */
    }

    

    private static void createApplicationDirectoriesAndPropFile() throws IOException {
        File dir = new File(Constants.getDefaultIndexDirectoryPath());
        if (!dir.mkdirs()) {
            throw new IOException("Cannot create directory '" + dir.getPath() + "'");
        }
        File propsFile = new File(Constants.getApplicationPropertiesFilePath());
        propsFile.createNewFile();
    }

    private static boolean isAlreadyRunning() throws RuntimeException {
        /*
         * Check if application already running
         */
        try {
            lockFile = new File(System.getProperty("user.home")
                    + File.separator + "fasea.lock");
            // Check if the lock exist
            if (lockFile.exists()) {
                // if exist try to delete it
                lockFile.delete();
            }
            // Try to get the lock
            channel = new RandomAccessFile(lockFile, "rw").getChannel();
            lock = channel.tryLock();
            if (lock == null) {
                // File is lock by other application
                channel.close();
                JOptionPane.showMessageDialog(null,
                        "Another instance of Fasea is already running.",
                        "Fasea",
                        JOptionPane.ERROR_MESSAGE,
                        ImageControl.getImageControl().getErrorIcon());
                return true;
            }
        } catch (IOException e) {
            throw new RuntimeException("Could not start process.", e);
        }
        return false;
    }

    private static void createShutdownHook() {
        // Add shutdown hook to release lock when application shutdown
        ShutdownHook shutdownHook = new ShutdownHook();
        Runtime.getRuntime().addShutdownHook(shutdownHook);
    }

    private static void unlockFile() {
        // release and delete file lock
        try {
            if (lock != null) {
                lock.release();
                channel.close();
                lockFile.delete();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //TODO: Fix this
    private static void killSearchFrame() {
       // if (searchFrame != null) {
       //     searchFrame.setVisible(false);
       // }
    }

    private static boolean isFirstCall() {
        File dir = new File(Constants.getDefaultIndexDirectoryPath());
        return !dir.exists();
    }

    private static class ShutdownHook extends Thread {

        @Override
        public void run() {
            unlockFile();
            killSearchFrame();
        }
    }
    private static File lockFile;
    private static FileChannel channel;
    private static FileLock lock;
}
